﻿using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using log4net;
using System.Drawing;
using System.Collections.Generic;

namespace SopCastRecorder
{
	public partial class Form1 : Form
	{
		private static ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			try
			{
				this.Init();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void Init()
		{
			SopCastRecorderMainForm = this;
			this.scheduleHeaderControl1.OrderByPath = this.OrderByPath;
			this.scheduleHeaderControl1.OrderByChannel = this.OrderByChannel;
			this.scheduleHeaderControl1.OrderByTime = this.OrderByTime;
			this.scheduleHeaderControl1.OrderByWeek = this.OrderByWeek;
			this.InitScheduleControl();
		}

		private void InitScheduleControl()
		{
			for (var i = 0; i < OptionFile.Option1.ScheduleInfoes.Count(); i++)
			{
				this.AddScheduleControl(OptionFile.Option1.ScheduleInfoes[OptionFile.Option1.ScheduleInfoes.Count() - 1 - i]);
			}
		}

		private void AddScheduleControl(ScheduleInfo scheduleInfo1)
		{
			var scheduler = new ScheduleControl()
			{
				scheduleInfo1 = scheduleInfo1,
				DeleteFunction = this.DeleteScheduleInfo,
				Dock = DockStyle.Top
			};
			this.pnlScheduler.Controls.Add(scheduler);
		}


		private void btnStart_Click(object sender, EventArgs e)
		{
			try
			{
				this.StartStop();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void StartStop()
		{
			if (this.btnStart.Status1 == StartButton.Status.Start)
			{
				this.Start();
			}
			else
			{
				this.Stop();
			}
		}

		private void Start()
		{
			this.ResetErrorStatus();
			this.WriteOption();
			if (!this.Validation())
			{
				return;
			}
			Timer.Start();
			this.btnStart.ChangeStatus(StartButton.Status.Stop);
		}

		private bool Validation()
		{
			bool isContinue = true;
			OptionFile.Validation((isSopCastPath) =>
			{
				if (!isSopCastPath)
				{
					isContinue = false;
					MessageBox.Show("SopCast.exe was not found .\nPlease check Option->SopCastPath .");
				}
			});
			return isContinue;
		}

		private void ResetErrorStatus()
		{
			this.btnError.BackColor = this.btnStart.BackColor;
		}

		private static Form1 SopCastRecorderMainForm;
		public static void SetErrorStatus()
		{
			SopCastRecorderMainForm.btnError.BackColor = Color.Red;
		}

		private void WriteOption()
		{
			this.RefreshScheduleInfo();
			OptionFile.Write();
		}

		private void RefreshScheduleInfo()
		{
			foreach (ScheduleControl scheduleControl1 in this.pnlScheduler.Controls)
			{
				scheduleControl1.RefreshScheduleInfo();
			}
		}

		private void Stop()
		{
			Timer.Stop();
			this.btnStart.ChangeStatus(StartButton.Status.Start);
		}

		private void btnAdd_Click(object sender, EventArgs e)
		{
			try
			{
				this.Add();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void Add()
		{
			var scheduleInfo1 = new ScheduleInfo();
			OptionFile.Option1.ScheduleInfoes.Add(scheduleInfo1);
			this.WriteOption();
			this.AddScheduleControl(scheduleInfo1);
		}

		private void btnOption_Click(object sender, EventArgs e)
		{
			try
			{
				this.Option();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void Option()
		{
			this.WriteOption();
			var form = new OptionForm();
			form.CallbackOk = this.Reload;
			form.Show();
		}

		private void btnReload_Click(object sender, EventArgs e)
		{
			try
			{
				this.Reload();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void Reload()
		{
			this.pnlScheduler.Controls.Clear();
			OptionFile.Read();
			this.InitScheduleControl();
		}

		public void DeleteScheduleInfo(ScheduleInfo info)
		{
			OptionFile.Option1.ScheduleInfoes.Remove(info);
			var scheduleControls1 =
				from ScheduleControl p in this.pnlScheduler.Controls
				where p.scheduleInfo1 == info
				select p;
			if (scheduleControls1.Count() > 0)
			{
				this.pnlScheduler.Controls.Remove(scheduleControls1.First());
			}
		}

		private void Form1_FormClosing(object sender, FormClosingEventArgs e)
		{
			try
			{
				this.CloseFunction();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void CloseFunction()
		{
			Timer.Stop();
			this.WriteOption();
		}

		private void btnError_Click(object sender, EventArgs e)
		{
			try
			{
				new ErrorForm().Show();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void OrderBy(List<ScheduleInfo> schedules)
		{
			this.RefreshScheduleInfo();
			OptionFile.Option1.ScheduleInfoes = schedules.ToList();
			OptionFile.Write();
			this.Reload();
		}

		private void OrderByPath(bool isAsc)
		{
			IEnumerable<ScheduleInfo> schedules;
			if (isAsc)
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.Path
					select p;
			}
			else
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.Path descending
					select p;
			}
			this.OrderBy(schedules.ToList());
		}

		private void OrderByChannel(bool isAsc)
		{
			IEnumerable<ScheduleInfo> schedules;
			if (isAsc)
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.Channel
					select p;
			}
			else
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.Channel descending
					select p;
			}
			this.OrderBy(schedules.ToList());
		}

		private void OrderByTime(bool isAsc)
		{
			IEnumerable<ScheduleInfo> schedules;
			if (isAsc)
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.Date, p.StartTime, p.EndTime
					select p;
			}
			else
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.Date descending, p.StartTime descending, p.EndTime descending
					select p;
			}
			this.OrderBy(schedules.ToList());
		}

		private void OrderByWeek(bool isAsc)
		{
			IEnumerable<ScheduleInfo> schedules;
			if (isAsc)
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.WeekSun, p.WeekMon, p.WeekTue, p.WeekWed, p.WeekThu, p.WeekFri, p.WeekSat
					select p;
			}
			else
			{
				schedules =
					from p in OptionFile.Option1.ScheduleInfoes
					orderby p.WeekSun descending, p.WeekMon descending, p.WeekTue descending, p.WeekWed descending, p.WeekThu descending, p.WeekFri descending, p.WeekSat descending
					select p;
			}
			this.OrderBy(schedules.ToList());
		}
	}
}
